package main

import "fmt"

type FnTy func(uint8, uint8) uint8

var A = [][]uint8{
	{0, 1}, {0, 2}, {0, 3}, {1, 0}, {1, 2}, {1, 3},
	{2, 0}, {2, 1}, {2, 3}, {3, 0}, {3, 1}, {3, 2},
}

var B = [][]uint8{
	{0, 1, 2}, {0, 1, 3}, {0, 2, 1}, {0, 2, 3}, {0, 3, 1}, {0, 3, 2},
	{1, 0, 2}, {1, 0, 3}, {1, 2, 0}, {1, 2, 3}, {1, 3, 0}, {1, 3, 2},
	{2, 0, 1}, {2, 0, 3}, {2, 1, 0}, {2, 1, 3}, {2, 3, 0}, {2, 3, 1},
	{3, 0, 1}, {3, 0, 2}, {3, 1, 0}, {3, 1, 2}, {3, 2, 0}, {3, 2, 1},
}

var FS = []FnTy{
	func(p, n uint8) uint8 { return p & n },
	func(p, n uint8) uint8 { return p | n },
	func(p, n uint8) uint8 { return p ^ n },
	func(p, n uint8) uint8 { return ^p & n },
	func(p, n uint8) uint8 { return p & ^n },
	func(p, n uint8) uint8 { return ^p & ^n },
	func(p, n uint8) uint8 { return ^p | n },
	func(p, n uint8) uint8 { return p | ^n },
	func(p, n uint8) uint8 { return ^p | ^n },
	func(p, n uint8) uint8 { return ^p | ^n },
}

var x, y, z, a, b, c uint8

/*
x:'0',y:'1',z:'_',a:'0',b:'1',c:'2'
(x,a) -> (x,a)
(x,b) -> (y,a)
(x,c) -> (x,b)
(y,a) -> (y,b)
(y,b) -> (x,c)
(y,c) -> (y,c)
(z,a) -> (z,a)
(z,b) -> (x,b)
(z,c) -> (z,c)
*/

func ck(f1, f2 FnTy, p1, n1, p2, n2 uint8) bool {
	return (f1(p1, n1) == p2) && (f2(p1, n1) == n2)
}

func main() {
	
	for _, p := range B {
		for _, n := range B {
			x = p[0]
			y = p[1]
			z = p[2]
			a = n[0]
			b = n[1]
			c = n[2]

			rd := [][]uint8{
				{x, a, x, a}, {x, b, y, a}, {x, c, x, b},
				{y, a, y, b}, {y, b, x, c}, {y, c, y, c},
				{z, a, z, a}, {z, b, z, b}, {z, c, z, c},
			}

			for i := 0; i < len(FS); i++ {
				for j := 0; j < len(FS); j++ {
					if i == j {
						continue
					}
					/*
						if !(FS[i](x,a) == x && FS[j](x,a)== a) {continue}
						if !(FS[i](x,b) == y && FS[j](x,b)== a) {continue}
						if !(FS[i](x,c) == x && FS[j](x,c)== b) {continue}
						if !(FS[i](y,a) == y && FS[j](x,a)== b) {continue}
						if !(FS[i](y,b) == x && FS[j](x,b)== c) {continue}
						if !(FS[i](y,c) == y && FS[j](x,c)== c) {continue}
						if !(FS[i](z,a) == z && FS[j](z,a)== a) {continue}
						if !(FS[i](z,b) == z && FS[j](z,b)== b) {continue}
						if !(FS[i](z,c) == z && FS[j](z,c)== c) {continue}
					*/
					
					count:=0;

					for k := 0; k < 6; k++ {
						if !ck(FS[i], FS[j], rd[k][0], rd[k][1], rd[k][2], rd[k][3]) {
							break
						}
						count++
					}

					if count == 6 {
						fmt.Printf("i:%d,j:%d,x:%b,y:%b,z:%b,a:%b,b:%b,c:%b\n", i, j, x, y, z, a, b, c)
					}
				}
			}
		}
	}
	// fmt.Printf("count:",count)

}
